package com.xyh.flowershop.service.websocket;

import com.alibaba.fastjson.JSON;
import com.xyh.flowershop.vo.req.message.Message;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author 小约翰可汗
 * @className WebSocketServer
 * @createTime 2024/7/2111:59
 */
@Slf4j
@ServerEndpoint("/websocket/chat/{userId}")
@Component
public class WebSocketServer {

    // 记录当前在线连接数
//    private static AtomicInteger onlineCount = new AtomicInteger(0);

    private static Map<String, Session> sessionMap = new ConcurrentHashMap<>();

    public void sendMessage(String message, Session session){
        if(Objects.nonNull(session)){
            synchronized (session) {
                log.info("WebSocketServer sendMessage: " + message);
                    // 发送消息到客户端
                    session.getAsyncRemote().sendText(message);
                }
            }
        }

    /**
     * 给指定用户发送消息
      * @param message
     * @param userId
     */
    public  void sendInfo(String message, String userId){
        // 从中获取session
        Session session = sessionMap.get(userId);
        try{
            sendMessage(message, session);
        }catch (Exception e){
            log.error("WebSocketServer sendInfo error: " + e.getMessage());
        }
    }

    /**
     * 发布公告消息
     * @param message
     */
    public void broadcast(String message){
        // 遍历sessionMap
        for(Session session : sessionMap.values()){
            try{
                sendMessage(message, session);
            }catch (Exception e){
                log.error("WebSocketServer broadcast error: " + e.getMessage());
            }
        }
    }

    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session){
        // TODO 进行token验证

        sessionMap.put(userId, session);
        log.info("用户编号：" + userId + "上线，当前在线人数: " + getInLineCount());
        // 发送系统消息
    }

    @OnMessage
    public void onMessage(String message){
        // 单纯发送消息
        log.info("WebSocketServer onMessage: " + message);
        Message msg = JSON.parseObject(message, Message.class);
        log.info("WebSocketServer onMessage: " + msg.toString());
        if(msg.getIsBroadcast()){
            broadcast(message);
        }else{
            sendInfo(message, msg.getTo());
        }
    }

    @OnClose
    public void onClose(@PathParam("userId") String userId){
        sessionMap.remove(userId);
        log.info("用户编号：" + userId + "下线，当前在线人数: " + getInLineCount());
    }

    @OnError
    public void onError(Session session, Throwable error){
        log.error("WebSocketServer onError: " + error.getMessage());
    }

    public int getInLineCount(){
        return sessionMap.size();
    }

}
